import os
import datetime
import shutil
import json

class DataBackupRestoreTool:
    def __init__(self, data_file_path, backup_dir_path=None):
        self.data_file_path = data_file_path
        self.backup_dir_path = backup_dir_path or os.path.join(os.path.dirname(data_file_path), "backups")
        
        # 确保备份目录存在
        if not os.path.exists(self.backup_dir_path):
            os.makedirs(self.backup_dir_path)
            print(f"Backup directory created: {self.backup_dir_path}")
    
    def create_backup(self, description=""):
        """创建数据备份"""
        try:
            # 生成备份文件名
            timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
            description_part = f"_{description}" if description else ""
            backup_filename = f"data_backup_{timestamp}{description_part}.json"
            backup_path = os.path.join(self.backup_dir_path, backup_filename)
            
            # 验证数据文件的完整性
            if self.verify_data_integrity():
                # 复制数据文件到备份位置
                shutil.copy2(self.data_file_path, backup_path)
                
                print(f"✅ Backup created successfully: {backup_path}")
                return backup_path
            else:
                print("❌ Data file integrity check failed. Backup aborted.")
                return None
        except Exception as e:
            print(f"❌ Failed to create backup: {str(e)}")
            return None
    
    def list_backups(self):
        """列出所有备份"""
        try:
            backups = []
            for filename in os.listdir(self.backup_dir_path):
                if filename.startswith("data_backup_") and filename.endswith(".json"):
                    filepath = os.path.join(self.backup_dir_path, filename)
                    # 获取文件信息
                    file_stats = os.stat(filepath)
                    created_time = datetime.datetime.fromtimestamp(file_stats.st_mtime)
                    backups.append({
                        "filename": filename,
                        "path": filepath,
                        "size": file_stats.st_size,
                        "created": created_time
                    })
            
            # 按创建时间排序(最新的在前)
            backups.sort(key=lambda x: x["created"], reverse=True)
            
            return backups
        except Exception as e:
            print(f"❌ Failed to list backups: {str(e)}")
            return []
    
    def restore_from_backup(self, backup_filename=None):
        """从备份恢复数据"""
        try:
            # 如果没有指定备份文件,列出备份供选择
            if not backup_filename:
                backups = self.list_backups()
                if not backups:
                    print("❌ No backups found.")
                    return False
                
                print("Available backups:")
                for i, backup in enumerate(backups, 1):
                    print(f"{i}. {backup['filename']} ({backup['created'].strftime('%Y-%m-%d %H:%M:%S')}, {backup['size']} bytes)")
                
                choice = input("Select a backup to restore (1-{}): ".format(len(backups))).strip()
                try:
                    backup_index = int(choice) - 1
                    if backup_index < 0 or backup_index >= len(backups):
                        print("❌ Invalid backup selection.")
                        return False
                    backup_path = backups[backup_index]["path"]
                except ValueError:
                    print("❌ Invalid input. Please enter a number.")
                    return False
            else:
                backup_path = os.path.join(self.backup_dir_path, backup_filename)
                
            # 检查备份文件是否存在
            if not os.path.exists(backup_path):
                print(f"❌ Backup file not found: {backup_path}")
                return False
            
            # 验证备份文件的完整性
            if not self.verify_backup_integrity(backup_path):
                print(f"❌ Backup file {backup_path} integrity check failed. Restore aborted.")
                return False
            
            # 在恢复前创建当前数据的备份
            self.create_backup("before_restore")
            
            # 恢复数据
            shutil.copy2(backup_path, self.data_file_path)
            
            print(f"✅ Data restored successfully from: {backup_path}")
            return True
        except Exception as e:
            print(f"❌ Failed to restore data: {str(e)}")
            return False
    
    # 新增:验证数据文件完整性
    def verify_data_integrity(self):
        """验证数据文件的完整性"""
        try:
            if not os.path.exists(self.data_file_path):
                print(f"❌ Data file not found: {self.data_file_path}")
                return False
            
            # 尝试加载并解析JSON文件
            with open(self.data_file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                
                # 检查必要的键是否存在
                required_keys = ['users', 'courses', 'progress', 'grades']
                for key in required_keys:
                    if key not in data:
                        print(f"❌ Missing required key '{key}' in data file")
                        return False
                
                return True
        except json.JSONDecodeError:
            print(f"❌ Data file is not valid JSON: {self.data_file_path}")
            return False
        except Exception as e:
            print(f"❌ Error verifying data integrity: {str(e)}")
            return False
    
    # 新增:验证备份文件完整性
    def verify_backup_integrity(self, backup_path):
        """验证备份文件的完整性"""
        try:
            if not os.path.exists(backup_path):
                print(f"❌ Backup file not found: {backup_path}")
                return False
            
            # 尝试加载并解析JSON文件
            with open(backup_path, 'r', encoding='utf-8') as f:
                json.load(f)  # 只需验证JSON格式是否正确
                return True
        except json.JSONDecodeError:
            print(f"❌ Backup file is not valid JSON: {backup_path}")
            return False
        except Exception as e:
            print(f"❌ Error verifying backup integrity: {str(e)}")
            return False
    
    # 新增:自动清理旧备份,保留最近的N个备份
    def cleanup_old_backups(self, max_backups=10):
        """清理旧备份,保留最近的指定数量的备份"""
        try:
            backups = self.list_backups()
            if len(backups) > max_backups:
                backups_to_delete = backups[max_backups:]
                for backup in backups_to_delete:
                    os.remove(backup['path'])
                    print(f"✅ Deleted old backup: {backup['filename']}")
                return len(backups_to_delete)
            return 0
        except Exception as e:
            print(f"❌ Failed to cleanup old backups: {str(e)}")
            return -1
